
<template>
  <div class="timer-container">
    <div class="timer-form">
        <div class="form-group">
            <label for="taskName">事项:</label>
            <input type="text" id="taskName" v-model="newTimer.taskName" required>
        </div>

        <div class="form-group">
            <label for="lastExecution">最近执行时间:</label>
            <input type="datetime-local" id="lastExecution" v-model="newTimer.lastExecution" step="1" required>
        </div>

        <div class="form-group">
            <label for="intervalMinutes">间隔时间(分钟):</label>
            <input type="number" id="intervalMinutes" v-model.number="newTimer.intervalMinutes" min="1" value="5" required>
        </div>

        <button @click="addTimer">添加计时器</button>
    </div>

    <div class="notification" id="notification" :style="{ display: notification.show ? 'block' : 'none' }">
        <span id="notificationText">{{ notification.message }}</span>
    </div>

    <table id="timersTable">
        <thead>
        <tr>
            <th>事项</th>
            <th>最近执行时间</th>
            <th>间隔时间(分钟)</th>
            <th>下次执行时间</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody id="timersList">
        <tr v-for="timer in sortedTimers" :key="timer.id">
            <td>{{ timer.taskName }}</td>
            <td>{{ formatDate(timer.lastExecution) }}</td>
            <td>{{ timer.intervalMinutes }}</td>
            <td>{{ formatDate(timer.nextExecution) }}</td>
            <td>
                <button v-if="isDue(timer)" class="edit-btn" @click="completeTimer(timer.id)">完成</button>
                <button class="delete-btn" @click="deleteTimer(timer.id)">删除</button>
            </td>
        </tr>
        </tbody>
    </table>

    <audio ref="alertSound" preload="auto">
        <source src="https://www.soundjay.com/misc/sounds/bell-ringing-05.wav" type="audio/wav">
    </audio>
  </div>
</template>

<script setup>import { ref, reactive, computed, onMounted, onBeforeUnmount } from 'vue'

// 定义响应式数据
const timers = ref([])
const timerId = ref(0)
const alertSound = ref(null)

// 新计时器表单数据
const newTimer = reactive({
    taskName: '',
    lastExecution: '',
    intervalMinutes: 5
})

// 通知状态
const notification = reactive({
    show: false,
    message: ''
})

// 计算属性：按下次执行时间排序的计时器
const sortedTimers = computed(() => {
    return [...timers.value].sort((a, b) => new Date(a.nextExecution) - new Date(b.nextExecution))
})

// 计算属性：判断计时器是否到期
const isDue = (timer) => {
    return new Date() >= new Date(timer.nextExecution)
}

// 格式化日期时间
const formatDate = (date) => {
    return new Date(date).toLocaleString('zh-CN', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit'
    }).replace(/\//g, '-')
}

// 设置默认时间
const setDefaultTime = () => {
    const now = new Date()
    const year = now.getFullYear()
    const month = String(now.getMonth() + 1).padStart(2, '0')
    const day = String(now.getDate()).padStart(2, '0')
    const hours = String(now.getHours()).padStart(2, '0')
    const minutes = String(now.getMinutes()).padStart(2, '0')
    const seconds = String(now.getSeconds()).padStart(2, '0')

    newTimer.lastExecution = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`
}

// 添加计时器
const addTimer = () => {
    if (!newTimer.taskName || !newTimer.lastExecution || isNaN(newTimer.intervalMinutes) || newTimer.intervalMinutes <= 0) {
        alert('请输入有效的事项、最近执行时间和间隔时间')
        return
    }

    const lastExecution = new Date(newTimer.lastExecution)
    const nextExecution = new Date(lastExecution.getTime() + newTimer.intervalMinutes * 60000)

    const timer = {
        id: ++timerId.value,
        taskName: newTimer.taskName,
        lastExecution: lastExecution,
        intervalMinutes: newTimer.intervalMinutes,
        nextExecution: nextExecution
    }

    timers.value.push(timer)
    saveTimers()
    renderTimers()

    // 重置表单
    newTimer.taskName = ''
    // 不重置时间，保持用户设置的时间
}

// 删除计时器
const deleteTimer = (id) => {
    timers.value = timers.value.filter(timer => timer.id !== id)
    saveTimers()
    renderTimers()
}

// 完成计时器任务
const completeTimer = (id) => {
    const timer = timers.value.find(t => t.id === id)
    if (!timer) return

    // 更新最近执行时间为当前时间
    const now = new Date()
    timer.lastExecution = now

    // 重新计算下次执行时间
    timer.nextExecution = new Date(now.getTime() + timer.intervalMinutes * 60000)

    // 保存并重新渲染
    saveTimers()
    renderTimers()

    // 显示完成通知
    showNotification(`任务 "${timer.taskName}" 已完成，下次执行时间已更新`, 5000)
}

// 渲染计时器列表（保持数据同步）
const renderTimers = () => {
    // 在Vue中不需要手动操作DOM，数据变化会自动更新视图
}

// 检查计时器
const checkTimers = () => {
    const now = new Date()
    let needSave = false

    timers.value.forEach(timer => {
        if (now >= new Date(timer.nextExecution)) {
            // 触发通知
            showNotification(`任务 "${timer.taskName}" 到达执行时间！`)

            // 播放音频
            if (alertSound.value) {
                alertSound.value.play().catch(e => console.log('音频播放失败:', e))
            }

            needSave = true
        }
    })

    if (needSave) {
        saveTimers()
        renderTimers()
    }
}

// 显示通知
const showNotification = (message, duration = 0) => {
    notification.message = message
    notification.show = true

    // 如果传入了持续时间，则在指定时间后自动隐藏
    if (duration > 0) {
        setTimeout(() => {
            notification.show = false
        }, duration)
    }
}

// 存储相关方法
const STORAGE_KEY = 'timers_data'

// 从 localStorage 加载定时器数据
const loadTimers = () => {
    try {
        const data = localStorage.getItem(STORAGE_KEY)
        if (data) {
            const parsed = JSON.parse(data)
            // 将日期字符串转换回 Date 对象
            timers.value = parsed.map(timer => ({
                ...timer,
                lastExecution: new Date(timer.lastExecution),
                nextExecution: new Date(timer.nextExecution)
            }))

            if (timers.value.length > 0) {
                timerId.value = Math.max(...timers.value.map(t => t.id))
            }
        }
    } catch (e) {
        console.error('加载定时器数据失败:', e)
    }
    return []
}

// 保存定时器数据到 localStorage
const saveTimers = () => {
    try {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(timers.value))
    } catch (e) {
        console.error('保存定时器数据失败:', e)
    }
}

// 清除所有定时器数据
const clearTimers = () => {
    localStorage.removeItem(STORAGE_KEY)
}

// 定时检查计时器
let checkInterval

// 组件挂载时
onMounted(() => {
    loadTimers()
    setDefaultTime()
    renderTimers()
    checkInterval = setInterval(checkTimers, 1000)
})

// 组件卸载前清理
onBeforeUnmount(() => {
    if (checkInterval) {
        clearInterval(checkInterval)
    }
})
</script>

<style scoped>
.timer-container {
    font-family: Arial, sans-serif;
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
    font-size: 14px;
}

.timer-form {
    background: #f5f5f5;
    padding: 20px;
    border-radius: 8px;
    margin-bottom: 20px;
}

.form-group {
    margin-bottom: 15px;
}

label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}

input, select {
    width: 100%;
    padding: 8px;
    border: 1px solid #ddd;
    border-radius: 4px;
    box-sizing: border-box;
}

button {
    background: #007bff;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button:hover {
    background: #0056b3;
}

table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 20px;
}

th, td {
    border: 1px solid #ddd;
    padding: 12px;
    text-align: left;
}

th {
    background-color: #f2f2f2;
}

.edit-btn {
    background: #28a745;
    padding: 5px 10px;
    font-size: 12px;
    margin-right: 5px;
}

.edit-btn:hover {
    background: #218838;
}

.delete-btn {
    background: #dc3545;
    padding: 5px 10px;
    font-size: 12px;
}

.delete-btn:hover {
    background: #c82333;
}

.notification {
    background: #28a745;
    color: white;
    padding: 15px;
    border-radius: 4px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    display: none;
}
</style>